use std::cell::RefCell;
use std::pin::Pin;
use std::rc::Rc;
use std::task::{Context, Poll, Waker};
use yew::Callback;
use crate::business::app_state::AppState;
use crate::business::websocket::send_data_router::{RpcRequest, RpcResponse};
use crate::business::websocket::receive_send_handle::ImReceiveSendHandleMsg;

#[derive(Debug)]
pub struct SendDataHandle {
    response: Rc<RefCell<Option<RpcResponse>>>,
    app_state: AppState,
    waker: Rc<RefCell<Option<Waker>>>,
}

impl Future for SendDataHandle {
    type Output = RpcResponse;

    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
        if self.response.borrow().is_some() {
            let t = self.response.clone().take().unwrap();
            Poll::Ready(t)
        } else {
            // cx.waker().wake_by_ref();
            let waker = cx.waker().clone();
            let mut c_waker = self.waker.borrow_mut();
            c_waker.replace(waker);
            Poll::Pending
        }
    }
}

impl SendDataHandle {
    pub fn new(app_state: AppState) -> SendDataHandle {
        Self {
            app_state,
            response: Rc::new(RefCell::new(None)),
            waker: Rc::new(RefCell::new(None)),
        }
    }

    pub fn set_result(&self, rpc_response: RpcResponse) {
        let mut response = self.response.borrow_mut();
        response.replace(rpc_response);
        if let Some(waker) = self.waker.take() {
            waker.wake_by_ref();
        }
    }

}

// 异步发送
pub async fn send_data_async(app_state2: AppState, request: RpcRequest) -> RpcResponse {
    let send_data_handle = SendDataHandle::new(app_state2);

    let send_data_handle_clone = send_data_handle.clone();
    let callback = Callback::from(move | result: RpcResponse| {
        log::info!("login callback: {:?}", result);
        send_data_handle_clone.set_result(result);

        log::info!("loginSuccess: redirect index");
    });

    let websocket_handle = send_data_handle.app_state.receive_send_handle.clone();
    if let Some(websocket_handle) = websocket_handle {
        websocket_handle.dispatch(ImReceiveSendHandleMsg::Request(request, callback));
    } else {
        log::info!("no websocket handle");
    }
    send_data_handle.await
}

// 回调发送
pub fn send_data_callback(app_state: AppState, request: RpcRequest, callback: Callback<RpcResponse>)  {
    let websocket_handle = app_state.receive_send_handle.clone();
    if let Some(websocket_handle) = websocket_handle {
        websocket_handle.dispatch(ImReceiveSendHandleMsg::Request(request, callback));
    } else {
        log::info!("no websocket handle");
    }
}

impl Clone for SendDataHandle {
    fn clone(&self) -> Self {
        Self {
            response: self.response.clone(),
            app_state: self.app_state.clone(),
            waker: self.waker.clone(),
        }
    }
}
